package com.yanboot.iot.utils;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yanboot.iot.utils.gb26875.enums.PacketElement;
import com.yanboot.iot.utils.gb26875.format.GB26875Mapper;
import com.yanboot.iot.utils.gb26875.properties.Message;
import com.yanboot.iot.utils.gb26875.properties.Message2;
import com.yanboot.iot.utils.gb26875.properties.MessageFactory;
import com.yanboot.iot.utils.gb26875.utils.AsciiUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;

import java.util.Arrays;
import java.util.Map;

/**
 * @Author fdj
 * @Date 2024/10/26 13:42
 * @Description 海康用传装置服务消息处理类
 */
@Slf4j
public class HikUserTransferServerHandler extends ChannelInboundHandlerAdapter {

//    @DubboReference
//    private RemoteKafkaService remoteKafkaService;

    private final String fireTopic = "alarm-fire-fighting";

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        try {
            byte[] bytes = new byte[buf.readableBytes()];
            buf.readBytes(bytes);

            // 解析
            GB26875Mapper gb26875Mapper = new GB26875Mapper();
            Map<String, Object> map = gb26875Mapper.readValue(bytes, Map.class);
            Map<String, Object> data = (Map<String, Object>) map.get("data");
            ObjectMapper objectMapper = new ObjectMapper();
            Message message = objectMapper.convertValue(data.get("msgData"), MessageFactory.getClassByType((Integer) data.get("msgDataType")));
            if (message instanceof Message2 message2) {
                if (message2.getPartDesc().contains("有火警")) {
                    log.warn("地址为{}的的消防探头发生火警信息", message2.getPartAddress());
//                    remoteKafkaService.send(fireTopic, IdUtil.fastSimpleUUID(), JSONUtil.toJsonStr(message2));
                }
            }
            // 组装响应
            byte[] resBytes = ackResponse(bytes);
            // 响应写入buf
            ByteBuf responseBuf = ctx.alloc().buffer(resBytes.length);
            responseBuf.writeBytes(resBytes);

            // 发送响应并刷新写操作
            ctx.writeAndFlush(responseBuf);
        } finally {
            buf.release();
        }
    }

    /**
     * 组装确认响应
     *
     * @param reqBytes 请求字节码数组
     * @return 相应字节码数组
     */
    private byte[] ackResponse(byte[] reqBytes) {
        // 响应
        byte[] resBytes = new byte[30];
        // 复制信息
        System.arraycopy(reqBytes, 0, resBytes, 0, 26);
        // 地址互换
        System.arraycopy(reqBytes, 12, resBytes, 18, 6);
        System.arraycopy(reqBytes, 18, resBytes, 12, 6);
        // 命令字节改为确认
        resBytes[26] = 3;
        // 结束符
        resBytes[28] = 35;
        resBytes[29] = 35;

        // 需要计算校验和的范围
        byte[] needCheckBytes = Arrays.copyOfRange(resBytes, PacketElement.HEADER.getLen(),
                resBytes.length - PacketElement.VERIFY.getLen() - PacketElement.FOOTER.getLen());
        // 待校验位长度
        byte b = AsciiUtil.sumCheck(needCheckBytes, PacketElement.VERIFY.getLen())[0];
        // 修改校验和
        resBytes[27] = b;
        return resBytes;
    }
}
